﻿using System;
using System.Collections.Generic;
using System.Drawing;
using GLWrap.SceneObjects;
using ReAnimation.Domain;
using ReAnimation.Graphics.Handlers.TwoAtomsSelect.States;
using ReAnimation.Helpers.Common;
using ReAnimation.Helpers.WinForms;

namespace ReAnimation.Graphics.Handlers.TwoAtomsSelect
{
    public class TwoAtomsSelectHandler:  BaseHandler, ITwoAtomsSelectHandler
    {
        public AtomEmphasizeParams FirstSelectedAtomEmphasizeParams { get; set; }
        public AtomEmphasizeParams SecondSelectedAtomEmphasizeParams { get; set; }

        public event EventHandler<EventArg<Pair<Atom, Atom>>> Selected;

        internal Atom FirstSelectedAtom { get; set; }
        internal Atom SecondSelectedAtom { get; set; }

        private IDictionary<SceneObject, Atom> _sceneToAtomMap;
        private IDictionary<TwoAtomsSelectStates, IState> _states;
        private IState _currentState;

        private TwoAtomsSelectStates _currentStateType;
        internal TwoAtomsSelectStates CurrentStateType
        {
            get
            {
                return _currentStateType;
            }
            set
            {
                _currentState.LeaveState();

                _currentStateType = value;
                _currentState = _states[value];

                _currentState.EnterState();
            }
        }

        public TwoAtomsSelectHandler(IMoleculeDrawer moleculeDrawer):base(moleculeDrawer)
        {
            FirstSelectedAtomEmphasizeParams = new AtomEmphasizeParams {Color = Color.Blue};
            SecondSelectedAtomEmphasizeParams = new AtomEmphasizeParams {Color = Color.Yellow};

            _states = new Dictionary<TwoAtomsSelectStates, IState>();
            _states[TwoAtomsSelectStates.FirstAtomSelect]  = new FirstAtomSelectState(this);
            _states[TwoAtomsSelectStates.SecondAtomSelect] = new SecondAtomSelectState(this);

            _currentState = new ZeroState(this);
            CurrentStateType = TwoAtomsSelectStates.FirstAtomSelect;           
        }

        protected override void PhysicallyStartHandle()
        {
            _sceneToAtomMap = MoleculeDrawer.SceneToAtomMap;
            CurrentStateType = TwoAtomsSelectStates.FirstAtomSelect;
        }

        protected override void PhysicallyStopHandle()
        {
            DeemphasizeSelected();
        }

        public void DeemphasizeSelected()
        {
            MoleculeDrawer.DeemphasizeAtoms(new List<Atom>{FirstSelectedAtom,SecondSelectedAtom});
            FirstSelectedAtom  = null;
            SecondSelectedAtom = null;
        }

        protected override void SceneObjectSelected(SceneObject sceneObject)
        {
            if (_sceneToAtomMap.ContainsKey(sceneObject))
            {
                Atom selectedAtom = _sceneToAtomMap[sceneObject];
                _currentState.AtomSelected(selectedAtom);
            }
        }

        internal void SelectionFinished()
        {
            var selectedAtoms = new Pair<Atom, Atom>(FirstSelectedAtom,SecondSelectedAtom);
            Selected.Throw(this,new EventArg<Pair<Atom, Atom>>(selectedAtoms));
        }
    }
}